package com.wnxy.sddfp.bank.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wnxy.sddfp.bank.entity.TradeLog;
import com.wnxy.sddfp.bank.mapper.TradeLogMapper;
import com.wnxy.sddfp.bank.service.ITradeLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wnxy.sddfp.common.model.dto.bank.BankCardAddDTO;
import com.wnxy.sddfp.common.model.dto.bank.SignatureDTO;
import com.wnxy.sddfp.common.model.dto.bid.BankBidDTO;
import com.wnxy.sddfp.common.model.dto.bid.BidBalanceDTO;
import com.wnxy.sddfp.common.model.vo.trade.BorrowSyncRecordVo;
import com.wnxy.sddfp.common.util.BaseResult;
import com.wnxy.sddfp.common.util.EncryptUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;

/**
 * <p>
 * 托管系统交易记录表 服务实现类
 * </p>
 *
 * @author Jet
 * @since 2023-07-26
 */
@Service
public class TradeLogServiceImpl extends ServiceImpl<TradeLogMapper, TradeLog> implements ITradeLogService {

    @Autowired
    private RestTemplate restTemplate;

    @SneakyThrows
    @Override
    public SignatureDTO proxyBindCardLog(BankCardAddDTO bankCardAddDTO) {
        //1、保存交易记录
        TradeLog tradeLog = new TradeLog();
        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        tradeLog.setReqType("USER_BIND_CARD");
        tradeLog.setObjectId(bankCardAddDTO.getUserId());
        tradeLog.setCreateDate(LocalDateTime.now());
        tradeLog.setSynchronizeStatus(0);
        baseMapper.insert(tradeLog);

        //2、返回结果
        SignatureDTO signatureDTO = new SignatureDTO();
        signatureDTO.setReqCode(bankCardAddDTO.getReqCode());
        signatureDTO.setPlatformNo("SDDFP");
        // 请求数据转为json字符串
        signatureDTO.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        // 访问银行托管系统的地址 (搭建银行托管系统：sddf-system-bank)
        signatureDTO.setBankUrl("http://localhost:5600/bank/user");

        return signatureDTO;
    }

    @Override
    public void modifyRequestStatus(String reqCode, int status) {
        this.update(Wrappers.lambdaUpdate(TradeLog.class)
                .set(TradeLog::getSynchronizeStatus, status)
                .set(TradeLog::getConfirmDate, LocalDateTime.now())
                .eq(TradeLog::getReqCode, reqCode)
        );
    }

    @Override
    public void syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {
        //1、保存交易日志，此时数据同步状态SynchronizeStatus值默认是0
        TradeLog tradeLog = new TradeLog();
        // 设置请求流水号
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        // 设置交易类型：CREATE表示创建操作
        tradeLog.setReqType("CREATE");
        // 设置对象唯一id，也就是业务主键
        tradeLog.setObjectId(borrowSyncRecordVo.getId());
        // 设置创建时间
        tradeLog.setCreateDate(LocalDateTime.now());
        // 设置同步状态：0未同步； 当调用银行托管系统成功返回后改为1已同步
        tradeLog.setSynchronizeStatus(0);
        // 保存交易日志
        this.save(tradeLog);

        //2、远程调用托管系统
        //2.1 请求基础路径；作为完成路径的一部分
        String url = "http://localhost:5600/service";
        //2.2 请求数据 - 对象转换为JSON， 使用alibaba提供的fastjson工具类(银行托管也是使用fastjson)
        String str = JSON.toJSONString(borrowSyncRecordVo);
        //2.3 对象加密处理： str ---> Base64编码 ---> URL编码 ---> 目标str
        // str ---> Base64编码
        String base64Str = EncryptUtil.encodeUTF8StringBase64(str);
        // Base64编码 ---> URL编码
        String reqData = EncryptUtil.encodeURL(base64Str);

        // 远程调用的方法：RestTemlate
        //String url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=xxx";
        sendHttpGet(url,"SYNC_BORROW_RECORD",reqData,tradeLog);
    }
    /**
     * 通过RestTemplate远程调用银行托管系统，修改交易日志状态为1已同步
     * @param url 银行托管系统请求基础路径
     * @param serviceName 区分托管系统不同方法的
     * @param reqData 请求数据的json格式
     * @param tradeLog 日志对象
     */
    private void sendHttpGet(String url,String serviceName,String reqData,TradeLog tradeLog) {
        // 拼接url
        StringBuffer sb = new StringBuffer();
        sb.append(url);
        sb.append("?serviceName=").append(serviceName);
        sb.append("&reqData=").append(reqData);

        // 通过RestTemplate远程调用银行托管系统
        // 远程调用返回json字符串
        String responseBody = restTemplate.getForObject(sb.toString(), String.class);
        // JSON转换为对象。（规矩接口规范：接口提供方提供了BaseResult对象）
        BaseResult baseResult = JSON.parseObject(responseBody, BaseResult.class);

        // 修改交易日志的同步状态、数据同步时间
        tradeLog.setSynchronizeStatus(1);
        tradeLog.setConfirmDate(LocalDateTime.now());
        this.updateById(tradeLog);
    }

    @Override
    public BidBalanceDTO getBidBalance(String userCode) {
        String requestUrl = "http://localhost:5600/bid/balance/" + userCode;
        BidBalanceDTO balanceDetailsDTO =
                restTemplate.getForObject(requestUrl, BidBalanceDTO.class);
        return balanceDetailsDTO;
    }
    @Override
    public BaseResult bankBidService(BankBidDTO bankBidDTO) {
        TradeLog tradeLog = new TradeLog();
        tradeLog.setReqCode(bankBidDTO.getReqCode());
        tradeLog.setObjectId(bankBidDTO.getId());
        tradeLog.setReqType(bankBidDTO.getBizType());
        tradeLog.setCreateDate(LocalDateTime.now());
        tradeLog.setSynchronizeStatus(0);

        this.save(tradeLog);

        String jsonString=JSON.toJSONString(bankBidDTO);
        String reqData=EncryptUtil.encodeUTF8StringBase64(jsonString);
        reqData = EncryptUtil.encodeURL(reqData);

        // 往银行托管系统发送借款数据,根据结果修改状态并返回结果
        String url="http://localhost:5600/service";
        sendHttpGet(url,"AGENCY_BID", reqData, tradeLog);

        BaseResult baseResult = new BaseResult();
        baseResult.setRespCode("200");
        return baseResult;
    }

}
